#include "Unit.h"
#include "Spell.h"
#include "Map.h"
#include "Loot.h"
#include "SimpleAudioEngine.h"

Unit::Unit(UnitTypeID _UnitTypeID)
{
	TempShowDamage.clear();
	m_UnitTypeID = _UnitTypeID;
	m_UnitDeadType = NotDead;
	m_PlayerFacing = Left;
	scheduleUpdate();
}

Unit::~Unit()
{

}
bool Unit::IsCastingSpell()
{
	return Map_Layer::GetInstance()->IsUnitCastingSpell(this);
}

void Unit::DealDamage(Unit* victim, int _CleanDamage, DamageType _DamageType)
{
	//Check CrashDamage Time
	if (_DamageType == CrashDamage)
	{
		if (!victim->ToPlayer()->CanTakeCrashDamage())
			return;
		else victim->ToPlayer()->SetCanTakeCrashDamage(false);
	}

	victim->ShowDamageNumber(_CleanDamage * 0.8 + rand() % _CleanDamage);
	if (victim->GetHeath() <= _CleanDamage)
	{
		victim->SetHeath(0);
		Kill(victim);
	}
	else
	{
		victim->SetHeath(victim->GetHeath() - _CleanDamage);
		if (victim->ToMonster())
			victim->ToMonster()->SetTarget(this);
	}
}

void Unit::CastSpell(int SpellID)
{
	if ((PlayerAction)SpellID == ATTACK_NORMAL)
	{
		stopAllActions();
		Spell* TempSpell = new Spell(((Unit*)this), ATTACK_NORMAL);
		GetFacing() == Left ? TempSpell->setPosition(getContentSize().width / 2 - TempSpell->GetAttackMovingPos(), getContentSize().height / 2) : TempSpell->setPosition(getContentSize().width / 2 + TempSpell->GetAttackMovingPos(), getContentSize().height / 2);
		GetFacing() == Left ? TempSpell->setFlipX(false) : TempSpell->setFlipX(true);
		addChild(TempSpell);
		CocosDenshion::SimpleAudioEngine::getInstance()->sharedEngine()->playEffect("sound/action/Attack1.wav");
		if (GetTypeId() == TypeID_Player)
		{
			CCSequence* spawn = CCSequence::create(ToPlayer()->GetAction(ATTACK_NORMAL), CallFunc::create(CC_CALLBACK_0(Unit::DesTorySprite, this, TempSpell)), NULL);
			TempSpell->runAction(spawn);
			ToPlayer()->SetCanDoAction(false);
			ToPlayer()->SetAttackTime(TempSpell->GetAttackTime());
			ToPlayer()->SetActionTime(TempSpell->GetAttackTime());
		}
		return;
	}
	else
	{
		//CastingSpell = new Spell(this, Id);
	}
}

void Unit::Kill(Unit* Killed)
{
	Killed->JustDead();
	if (Killed->ToMonster())
	{
		CocosDenshion::SimpleAudioEngine::getInstance()->sharedEngine()->playEffect("sound/action/Die.mp3");
		if (ToPlayer())
		{
			ToPlayer()->GetExpReward(10);
			Killed->CreateLoot(this);
		}
	}
}

void Unit::DesTorySprite(CCSprite* pSprite)
{
	pSprite->removeAllChildrenWithCleanup(true);
}

void Unit::ShowDamageNumber(int Damage, int roucount, bool cirt)
{
	//CCSprite* temp = new CCSprite();
	//temp->initWithFile("other/DamageNumbers/base1.png");
	//temp->autorelease();
	//temp->setPosition(getContentSize().width / 2, getContentSize().height / 2);
	//addChild(temp);
	char msg[100];
	snprintf(msg, 100, "%d", Damage);
	std::string change = msg;
	while (!change.empty())
	{
		int len = atoi(GetDamageNumber(change).c_str());
		CCSprite* temp = new CCSprite();//DamageNumberNormal.at(len);
		char url[255];
		snprintf(url, 255, "other/DamageNumbers/base%d.png", len);
		temp->initWithFile(url);
		temp->autorelease();
		TempShowDamage.push_back(temp);
	}
	float needweigth = TempShowDamage.size() * 20.0f;
	float firstX = getPositionX() - needweigth / 2;


	//show
	for (int i = 0; i != TempShowDamage.size(); i++)
	{
		TempShowDamage.at(i)->setPosition(firstX + i * 20.0f, getBoundingBox().size.height + getBoundingBox().origin.y);
		CCFadeOut* LogoFadeOut = CCFadeOut::create(3.0f);
		CCSequence* LogoSpawn = CCSequence::create(LogoFadeOut, CallFunc::create(CC_CALLBACK_0(Unit::DesTorySprite, this, TempShowDamage.at(i))), NULL);
		TempShowDamage.at(i)->runAction(LogoSpawn);
		Map_Layer::GetInstance()->addChild(TempShowDamage.at(i));
		if (!i)
		{
			CCSprite* Boom = new CCSprite();
			Boom->initWithFile("other/DamageNumbers/takedamage1.png");
			Boom->autorelease();
			Boom->setScale(0.5f);
			Boom->setPosition(TempShowDamage.at(i)->boundingBox().origin.x, TempShowDamage.at(i)->boundingBox().origin.y + TempShowDamage.at(i)->boundingBox().size.height);
			Map_Layer::GetInstance()->addChild(Boom);
			CCFadeOut* Fadeout = CCFadeOut::create(3.0f);
			CCSequence* spawn = CCSequence::create(Fadeout, CallFunc::create(CC_CALLBACK_0(Unit::DesTorySprite, this, Boom)), NULL);
			Boom->runAction(spawn);
		}
	}
	TempShowDamage.clear();
}


void Unit::JustDead()
{
	if (GetTypeId() == TypeID_Monster)
	{
		Map_Layer::GetInstance()->RemoveMonsterFromMapWhenDead(ToMonster());
		CCFadeOut* LogoFadeOut = CCFadeOut::create(3.0f);
		CCSequence* LogoSpawn = CCSequence::create(LogoFadeOut, CallFunc::create(CC_CALLBACK_0(Unit::DesTorySprite, this, ((Unit*)this))), NULL);
		runAction(LogoSpawn);
		m_UnitDeadType = Dead;
	}
	else
	{
		ToPlayer()->PlayerDead();
		m_UnitDeadType = Ghost;
	}
}

void Unit::CreateLoot(Unit* Killer)
{
	if (Monster* pMonster = ToMonster())
	{
		std::vector<MonsterLootSingleInfo> temp = Map_Scene::GetInstance()->GetLootTemplate(ToMonster()->GetEntry());
		std::vector<Loot*> TempLootVector;
		for (int i = 0; i != temp.size(); i++)
		{
			int chance = rand() % 100;
			if (chance <= temp.at(i).Chance)
			{
				Loot* pLoot = new Loot();
				pLoot->SetItemEntry(temp.at(i).Item_Entry);
				int count = temp.at(i).Count + rand() % temp.at(i).MaxCount;
				pLoot->SetCount(count);
				pLoot->SetOwner(Killer);
				char url[200];
				snprintf(url, 200, "ItemImage/%s.png", Map_Scene::GetInstance()->GetItemTemplate(temp.at(i).Item_Entry).Image_Url.c_str());
				if (pLoot->initWithFile(url))
					pLoot->autorelease();
				TempLootVector.push_back(pLoot);
			}
		}
		if (!TempLootVector.empty())
		{
			int Count = TempLootVector.size();
			float base_MonvePoint = 30.0f * (Count / 2);
			float Start_Point = getBoundingBox().origin.x + (getBoundingBox().size.width / 2) + base_MonvePoint;
			for (int i = 0; i != TempLootVector.size(); i++)
			{
				TempLootVector.at(i)->SetMovePostion(Start_Point - (i * 30.0f), getBoundingBox().origin.y + getBoundingBox().size.height);
				TempLootVector.at(i)->SetBasePostion(getPositionX(), getPositionY() - getBoundingBox().size.height / 2);
				TempLootVector.at(i)->setPosition(getPositionX(), getPositionY() - getBoundingBox().size.height / 2);
				TempLootVector.at(i)->AddToMap();
				Map_Layer::GetInstance()->addChild(TempLootVector.at(i));
				CocosDenshion::SimpleAudioEngine::getInstance()->sharedEngine()->playEffect("sound/action/DropItem.mp3");
			}
		}
	}
}

std::string Unit::GetDamageNumber(std::string& number)
{
	std::string getbak = "";
	std::string panduan = "";
	for (int i = 0; i < number.length() + 1000; i++)
	{
		if (number.empty())
			break;
		panduan = number.at(0);
		number.erase(0, 1);
		return panduan;
	}
}

void Unit::update(float diff)
{

}